// ***********************************************************************
// Copyright (c) 2021 SZ,All rights reserved.
// CLR Version      : 0.0.1
// Project          : Tools
// Assembly         : Tools
// Author           : Jimmy Teng
// Created          : 2019-08-28
// Description      : Async Timer
// ***********************************************************************
// Last Modified By : Jimmy Teng
// Last Modified On : 2019-08-28
// ***********************************************************************
#ifndef ASYNC_TIMER_HPP
#define ASYNC_TIMER_HPP
#include <cstdint>
#include <chrono>
#include <map>
#include <vector>
#include <mutex>
#include <iostream>
#include "P7_Trace.h"
#include "P7_Telemetry.h"
class AsyncLogger {
  AsyncLogger() = default;
 public:
  int Initialize(const std::string &str = "127.0.0.1");
  /// \brief GetInstance
  /// \return Instance Ptr
  static AsyncLogger *GetInstance();
  /// \brief Start Timer with timer id and call index
  /// \param id timer id
  /// \param index call index
  /// \return timestamp
  uint64_t TimerStart(const std::string &name, uint32_t index);
  /// \brief End Timer with timer id and call index
  /// \param id timer id
  /// \param index call index
  /// \param during timer during
  /// \param valid  timer valid
  /// \return timestamp
  uint64_t TimerEnd(const std::string &name, uint32_t index);
  /// \brief clear Timer
  /// \return
  void Clear();
  /// \brief Add Variable with name
  /// \param name
  /// \param variable
  /// \return
  int AddVariable(const std::string &name, double variable);
  /// \brief AddCount with name
  /// \param name
  /// \return
  int AddCount(const std::string &name);
 private:
  bool init_flg = false;
  std::mutex mtx_;
  std::map<std::string, uint16_t> variable_name_sendid_map_;
  std::map<std::string, uint16_t> count_name_sendid_map_;
  std::map<std::string, uint32_t> count_name_number_map_;
  std::map<std::string, uint32_t> timer_name_id_map_;
  std::map<uint64_t, uint64_t> timer_id_sendid_map_;
  std::map<uint64_t, uint64_t> timer_id_starttime_map_;
  IP7_Client *p_client_ = nullptr;
  IP7_Trace *p_trace_ = nullptr;
  IP7_Telemetry *p_telemetry_ = nullptr;
};
static std::mutex timer_mtx;
static uint32_t timer_count = 0;
class Timer {
 public:
  Timer(const std::string &name);
  ~Timer();;
 private:
  uint32_t index;
  std::string name_;
};

//************************************
// Method:    string_replace
// FullName:  string_replace
// Access:    public
// Returns:   void
// Qualifier: 把字符串的strsrc替换成strdst
// Parameter: std::string & strBig
// Parameter: const std::string & strsrc
// Parameter: const std::string & strdst
//************************************
void string_replace(std::string &strBig, const std::string &strsrc, const std::string &strdst);

//************************************
// Method:    GetFileOrURLShortName
// FullName:  GetFileOrURLShortName
// Access:    public
// Returns:   std::string
// Qualifier: 获取路径或URL的文件名（包括后缀，如 C:\Test\abc.xyz --> abc.xyz）
// Parameter: std::string strFullName
//************************************
std::string GetPathOrURLShortName(std::string strFullName);

#if NOLOG
AL_VARIABLE(name, variable)
#define AL_ADD_COUNT(name)
#define AL_FUNCTION_TIMER
#else
#define AL_VARIABLE(name, variable) AsyncLogger::GetInstance()->AddVariable((name),(variable));
#define AL_ADD_COUNT(name) AsyncLogger::GetInstance()->AddCount((name));
#define AL_FUNCTION_TIMER static std::string _al_time_name = GetPathOrURLShortName(std::string(__FILE__))+std::string(":")+std::string(__FUNCTION__); \
                          volatile Timer  timer(_al_time_name);
#endif

#endif //ASYNC_TIMER_HPP
